package com.hunter.api.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.apache.commons.lang3.StringUtils;
/**
 * @author HunterHuang
 * @version 1.0
 * @ClassName HttpServer
 * @date 2019/4/23 19:54
 */
public class JsonHelper {

    public static int getInteger(JSONObject json, String key, int def) {
        if(json == null || json.get(key)==null){
            return def;
        }
        String str=json.get(key).toString();
        if(StringUtils.isBlank(str)){
            return def;
        }

        return Integer.parseInt(json.get(key).toString());
    }

    public static long getLong(JSONObject json,String key,long def) {
        if(json == null || json.get(key)==null){
            return def;
        }
        String str=json.get(key).toString();
        if(StringUtils.isBlank(str)){
            return def;
        }

        return Long.parseLong(json.get(key).toString());
    }

    public static float getFloat(JSONObject json,String key,float def){
        if(json == null || json.get(key)==null){
            return def;
        }
        String str=json.get(key).toString();
        if(StringUtils.isBlank(str)){
            return def;
        }

        return Float.parseFloat(json.get(key).toString());
    }

    public static double getDouble(JSONObject json,String key,double def){
        if(json == null || json.get(key)==null){
            return def;
        }
        String str=json.get(key).toString();
        if(StringUtils.isBlank(str)){
            return def;
        }

        return Double.parseDouble(json.get(key).toString());
    }

    public static Object get(JSONObject json,String key,Object def){
        if(json == null || json.get(key)==null){
            return def;
        }

        return json.get(key);
    }

    public static String getString(JSONObject json,String key,String def){
        if(json == null || json.get(key)==null){
            return def;
        }
        return json.get(key).toString();
    }

    public static JSONObject getJSONObject(JSONObject json,String key,JSONObject def){
        if(json == null || json.get(key)==null){
            return def;
        }

        String str=json.get(key).toString();
        return toJSONObject(str,def);
    }

    public static JSONArray getJSONArray(JSONObject json, String key, JSONArray def){
        if(json == null || json.get(key)==null){
            return def;
        }
        return json.getJSONArray(key);
    }


    /**
     * 将 json字符串转换成 JSONObject
     *
     * @param str
     * @return
     */
    public static JSONObject toJSONObject(String str){
        return toJSONObject(str,null);
    }

    public static JSONObject toJSONObject(String str, JSONObject def){
        if(StringUtils.isBlank(str)){
            return def;
        }
        JSONObject obj=JSONObject.parseObject(str);
        return obj;
    }


    /**
     * 将 json字符串转换成 JSONArray
     *
     * @param str
     * @return
     */
    public static JSONArray toJSONArray(String str){
        return toJSONArray(str,null);
    }

    public static JSONArray toJSONArray(String str, JSONArray def){
        if(StringUtils.isBlank(str)){
            return def;
        }

        JSONArray obj= toJSONArray(str);
        return obj;
    }

    /**
     * 对JSONArray中的JSONObject做快速排序
     * 根据sortKeyStr, sortMode
     *
     * @param list
     * @param lo
     * @param hi
     */
    public static void sortQuick(JSONArray list, int lo, int hi, String sortKeyStr, boolean asc) {
        if (hi <= lo) {
            return;
        }

        int j = 0;
        if (asc) {
            j = partitionAsc(list, lo, hi, sortKeyStr);
        } else {
            j = partitionDesc(list, lo, hi, sortKeyStr);
        }

        sortQuick(list, lo, j - 1, sortKeyStr, asc);
        sortQuick(list, j + 1, hi, sortKeyStr, asc);
    }

    public static int partitionAsc(JSONArray list, int lo, int hi, String sortKeyStr) {
        int i = lo, j = hi + 1;
        JSONObject v = list.getJSONObject(lo);
        while (true) {
            while (less((list.getJSONObject(++i)), v, sortKeyStr)) {
                if (i == hi) {
                    break;
                }
            }
            while (less(v, (list.getJSONObject(--j)), sortKeyStr)) {
                if (j == lo) {
                    break;
                }
            }
            if (i >= j) {
                break;
            }
            exchange(list, i, j);
        }
        exchange(list, lo, j);
        return j;
    }

    public static int partitionDesc(JSONArray list, int lo, int hi, String sortKeyStr) {
        int i = lo, j = hi + 1;
        JSONObject v = (JSONObject) (list.get(lo));
        while (true) {
            while (greater((list.getJSONObject(++i)), v, sortKeyStr)) {
                if (i == hi) {
                    break;
                }
            }
            while (greater(v, (list.getJSONObject(--j)), sortKeyStr)) {
                if (j == lo) {
                    break;
                }
            }
            if (i >= j) {
                break;
            }
            exchange(list, i, j);
        }
        exchange(list, lo, j);
        return j;
    }

    private static boolean greater(JSONObject v, JSONObject w, String sortKeyStr) {
        Object vKey = v.get(sortKeyStr);
        Object wKey = w.get(sortKeyStr);

        if (vKey instanceof Number) {
            return Double.compare(Double.parseDouble(String.valueOf(vKey)), Double.parseDouble(String.valueOf(wKey))) > 0;
        } else {
            return String.valueOf(vKey).compareToIgnoreCase(String.valueOf(wKey)) > 0;
        }
    }

    private static boolean less(JSONObject v, JSONObject w, String sortKeyStr) {
        Object vKey = v.get(sortKeyStr);
        Object wKey = w.get(sortKeyStr);

        if (vKey instanceof Number) {
            return Double.compare(Double.parseDouble(String.valueOf(vKey)), Double.parseDouble(String.valueOf(wKey))) < 0;
        } else {
            return String.valueOf(vKey).compareToIgnoreCase(String.valueOf(wKey)) < 0;
        }
    }

    private static void exchange(JSONArray list, int i, int j) {
        JSONObject t = list.getJSONObject(i);
        list.set(i, list.getJSONObject(j));
        list.set(j, t);
    }
}
